package com.ebei.admin.controller;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.service.IService;
import com.ebei.admin.common.util.TreeUtil;
import com.ebei.admin.model.dto.MenuTree;
import com.ebei.admin.model.entity.SysMenu;
import com.ebei.admin.service.SysMenuService;
import com.ebei.common.constant.CommonConstant;
import com.ebei.common.util.R;
import com.ebei.common.util.Result;
import com.ebei.common.vo.MenuVO;
import com.ebei.common.web.BaseController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 *
 * @author crazypenguin
 * @version 1.0
 * @created 2018/4/17
 */
@RestController
@RequestMapping("/menu")
@Api(value = "菜单", description = "菜单接口")
public class MenuController extends BaseController {
    @Autowired
    private SysMenuService sysMenuService;

    /**
     * 通过用户名查询用户菜单
     *
     * @param role 角色名称
     * @return 菜单列表
     */
    @GetMapping("/findMenuByRole/{role}")
    public Set<MenuVO> findMenuByRole(@PathVariable String role) {
        return sysMenuService.findMenuByRole(role);
    }

    @ApiOperation(value = "根据角色获取菜单树",notes = "根据角色获取菜单树")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "roleCode", value = "角色编码", required = true),
        @ApiImplicitParam(name = "deviceType", value = "菜单类型", required = true)
    })
    @GetMapping("/findMenuTreeByRoleCode")
    public List<MenuTree> findMenuTreeByRoleCode(@RequestParam String roleCode,String deviceType){
        return sysMenuService.findMenuTreeByRoleNameAndDeviceType(roleCode,deviceType);
    }

    @ApiOperation(value = "获取子菜单",notes = "根据设备类型获取子菜单")
    @ApiImplicitParam(name = "deviceType", value = "设备类型", required = true)
    @GetMapping("/getSubMenuByDevice")
    public Result<List<MenuTree>> getSubMenuByDevice(){
        Result<List<MenuTree>> result = new Result<>();

        SysMenu condition1 = new SysMenu();
        condition1.setDeviceType("0");
        condition1.setParentId(-1);
        condition1.setDelFlag(CommonConstant.STATUS_NORMAL);
        List<SysMenu> menus = sysMenuService.selectList(new EntityWrapper<>(condition1));

        return new Result<>(getMenuTree(menus,-1),Result.SUCCESS,"获取成功");
    }

    @ApiOperation(value = "获取子菜单",notes = "根据父菜单获取子菜单")
    @ApiImplicitParam(name = "parentId", value = "父菜单id", required = true)
    @GetMapping("/getSubMenuByParent")
    public Result<List<MenuTree>> getSubMenuByParent(@RequestParam Integer parentId){
        Result<List<MenuTree>> result = new Result<>();
        if(parentId == null){
            result.setErrorCode(Result.FAIL);
            result.setErrorMessage("菜单id不能为空");
            return result;
        }

        SysMenu condition1 = new SysMenu();
        condition1.setParentId(parentId);
        condition1.setDelFlag(CommonConstant.STATUS_NORMAL);
        List<SysMenu> menus = sysMenuService.selectList(new EntityWrapper<>(condition1));

        result.setErrorMessage("获取成功");
        result.setErrorCode(Result.SUCCESS);
        result.setData(getMenuTree(menus,parentId));
        return result;
    }

    /**
     * 返回当前用户的树形菜单集合
     * @return 当前用户的树形菜单
     */
    @GetMapping(value = "/getUserTree")
    public List<MenuTree> getUserTree(){
        return sysMenuService.findUserMenuTree(getRole().get(0));
    }

    /**
     * 返回当前用户树形菜单集合
     *
     * @return 树形菜单
     */
    @GetMapping("/userTree")
    public List<Integer> userTree() {
        Set<MenuVO> menus = sysMenuService.findMenuByRole(getRole().get(0));
        List<Integer> menuList = new ArrayList<>();
        for (MenuVO menuVo : menus) {
            menuList.add(menuVo.getMenuId());
        }
        return menuList;
    }

    /**
     * 返回角色的菜单集合
     *
     * @param roleName 角色名称
     * @return 属性集合
     */
    @GetMapping("/roleTree/{roleName}")
    public List<Integer> roleTree(@PathVariable String roleName) {
        Set<MenuVO> menus = sysMenuService.findMenuByRole(roleName);
        List<Integer> menuList = new ArrayList<>();
        for (MenuVO menuVo : menus) {
            menuList.add(menuVo.getMenuId());
        }
        return menuList;
    }

    @ApiOperation(value = "添加菜单",notes = "添加菜单")
    @ApiImplicitParam(name = "sysMenu", value = "菜单实体", required = true)
    @PostMapping(value = "/menuAdd")
    public Result<Boolean> menuAdd(@RequestBody SysMenu sysMenu) {
        if(!SysMenu.MENU_TYPE_CD.equals(sysMenu.getMenuType())){
            sysMenu.setPermission(sysMenu.getUrl());
            sysMenu.setUrl(null);
        }
        sysMenu.setCreateTime(new Date());
        sysMenu.setSort(sysMenuService.getSort(sysMenu.getParentId(),sysMenu.getDeviceType()));

        if(sysMenuService.insert(sysMenu)){
            return new Result<>(Boolean.TRUE,Result.SUCCESS,"新增菜单成功");
        }else{
            return new Result<>(Boolean.FALSE,Result.FAIL,"新增菜单失败");
        }
    }

    @ApiOperation(value = "删除菜单",notes = "删除菜单")
    @ApiImplicitParam(name = "id", value = "菜单ID", required = true)
    @PostMapping("/menuDel")
    public Result<Boolean> menuDel(@RequestBody Map<String, Object> params) {
        Result<Boolean> result = new Result<>();
        Integer id = Integer.valueOf(params.get("id").toString());
        // 当前节点有子节点则不允许删除
        SysMenu conditon = new SysMenu();
        conditon.setParentId(id);
        conditon.setDelFlag(CommonConstant.STATUS_NORMAL);
        List children = sysMenuService.selectList(new EntityWrapper<>(conditon));
        if(children != null && children.size() > 0){
            result.setErrorCode(Result.FAIL);
            result.setErrorMessage("存在子节点");
            return result;
        }
        if(id != null || !"".equals(id)){
            SysMenu sysMenu = sysMenuService.selectById(id);
            sysMenu.setDelFlag(CommonConstant.STATUS_DEL);
            if(sysMenuService.updateById(sysMenu)){
                result.setErrorMessage("删除成功");
                result.setErrorCode(Result.SUCCESS);
            }else{
                result.setErrorMessage("删除失败");
                result.setErrorCode(Result.FAIL);
            }
        }else{
            result.setErrorMessage("菜单id为空");
            result.setErrorCode(Result.FAIL);
        }
        return result;
    }

    @ApiOperation(value = "更新菜单",notes = "更新菜单")
    @ApiImplicitParam(name = "sysMenu", value = "菜单实体", required = true)
    @PostMapping(value = "/menuUpdate")
    public Result<Boolean> menuUpdate(@RequestBody SysMenu sysMenu) {
        Result<Boolean> result = new Result<>();
        sysMenu.setUpdateTime(new Date());
        if(sysMenuService.updateById(sysMenu)){
            result.setErrorMessage("更新成功");
            result.setErrorCode(Result.SUCCESS);
        }else{
            result.setErrorMessage("更新失败");
            result.setErrorCode(Result.FAIL);
        }
        return result;
    }

    private List<MenuTree> getMenuTree(List<SysMenu> menus, int root) {
        List<MenuTree> trees = new ArrayList<MenuTree>();
        MenuTree node = null;
        for (SysMenu menu : menus) {
            node = new MenuTree();
            node.setId(menu.getMenuId());
            node.setParentId(menu.getParentId());
            node.setName(menu.getMenuName());
            node.setCreateDate(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(menu.getCreateTime()));
            if(SysMenu.MENU_TYPE_CD.equals(menu.getMenuType()) || SysMenu.MENU_TYPE_MODEL.equals(menu.getMenuType())){
                node.setUrl(menu.getUrl());
            }else if(SysMenu.MENU_TYPE_AN.equals(menu.getMenuType())){
                node.setUrl(menu.getPermission());
            }else if(SysMenu.MENU_TYPE_GN.equals(menu.getMenuType())){
                node.setUrl(menu.getPermission());
            }
            else if(SysMenu.MENU_TYPE_MK.equals(menu.getMenuType())){
                node.setUrl(menu.getPermission());
            }
            node.setType(menu.getMenuType());
            node.setOpen(false);
            node.setMenuCode(menu.getMenuCode());
            trees.add(node);
        }
        return TreeUtil.bulid(trees, root);
    }
}
